package com.zhkj.crawl.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.zhkj.crawl.config.Config;
import com.zhkj.crawl.config.Constants;
import com.zhkj.crawl.config.StringPool;
import com.zhkj.crawl.entity.Listing;
import com.zhkj.crawl.entity.ListingRecord;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
import org.springframework.jdbc.core.namedparam.SqlParameterSourceUtils;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
@Slf4j
public class ListingService {
    @Autowired
    private NamedParameterJdbcTemplate jdbcTemplate;


    /**
     * 拉取待处理的listing（未处理||重试次数小于Config.MAX_RETRY_LISTING）
     * @param limit
     * @param plat
     * @return
     */
    public List<Listing> getUndoList(Integer limit, String plat){
        List<Listing> listing = getListing(limit, plat);
        if(CollUtil.isEmpty(listing)){
            listing = getListingRetry(limit, plat);
        }
        return listing;
    }
    public List<Listing> getListing(Integer limit, String plat){
        String month = Constants.getCurMon();
        String platSql = StringPool.EMPTY;
        String siteSql = StringPool.EMPTY;
        if(StringUtils.isNotBlank(plat)){
            platSql = String.format("AND plat='%s'", plat);
        }
        if(StringUtils.isNotBlank(Config.SITE_CURRENT)){
            String tmp = Config.SITE_CURRENT, val = StringPool.EMPTY;
            if(tmp.contains(StringPool.COMMA)){
                for (String s : tmp.split(StringPool.COMMA)) {
                    val += String.format("'%s',", s);
                }
                val = val.substring(0, val.length() - 1);
                siteSql = String.format("AND site in(%s)", val);
            }else {
                siteSql = String.format("AND site='%s'", tmp);
            }
        }

        String orderBy = Constants.isWindows ? "ASC" : "DESC";

        String sql = String.format("SELECT * FROM listing%s WHERE last_opt_month<%s AND STATUS=0 %s %s ORDER BY plat_id %s LIMIT %s", Config.TB_CURRENT, month, siteSql, platSql, orderBy, limit);
        return jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(Listing.class));
    }
    /**
     * 拉取状态2的listing重试
     * @param limit
     * @param plat
     * @return
     */
    public List<Listing> getListingRetry(Integer limit, String plat){
        int maxRetry = Config.MAX_RETRY_LISTING;
        String month = Constants.getCurMon();
        String platSql = StringPool.EMPTY;
        String siteSql = StringPool.EMPTY;
        if(StringUtils.isNotBlank(plat)){
            platSql = String.format("AND plat='%s'", plat);
        }
        if(StringUtils.isNotBlank(Config.SITE_CURRENT)){
            String tmp = Config.SITE_CURRENT, val = StringPool.EMPTY;
            if(tmp.contains(StringPool.COMMA)){
                for (String s : tmp.split(StringPool.COMMA)) {
                    val += String.format("'%s',", s);
                }
                val = val.substring(0, val.length() - 1);
                siteSql = String.format("AND site in(%s)", val);
            }else {
                siteSql = String.format("AND site='%s'", tmp);
            }
        }
        String orderBy = Constants.isWindows ? "ASC" : "DESC";

        String sql = String.format("SELECT * FROM listing%s WHERE last_opt_month=%s AND STATUS=2 %s AND REMARK<%s %s ORDER BY plat_id %s LIMIT %s", Config.TB_CURRENT, month, siteSql, maxRetry, platSql, orderBy, limit);
        return jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(Listing.class));
    }

    public long batchSave(List<ListingRecord> listings){
//        String month = Constants.getCurMon();
        Map<String, Object>[] values = new HashMap[listings.size()];
        for (int i = 0; i < listings.size(); i++) {
            ListingRecord listing = listings.get(i);
            values[i] = new HashMap<>();
            values[i].put("id", listing.getId());
            values[i].put("site", listing.getSite());
            values[i].put("plat_id", listing.getAsin());
        }
        String sql = String.format("INSERT ignore INTO `listing%s`(`id`,`from`,`plat`,`site`,`plat_id`,`last_opt_month`) VALUES " +
                "(:id,'php','亚马逊',:site,:plat_id,'%s')", Config.TB_CURRENT, "");

//        String sql = String.format("INSERT INTO `listing%s`(`id`,`from`,`plat`,`site`,`plat_id`,`last_opt_month`) VALUES " +
//                "(:id,'php','亚马逊',:site,:plat_id,'%s') ON DUPLICATE KEY UPDATE update_time=VALUES(update_time)", Config.TB_CURRENT, month);
        int[] rets = jdbcTemplate.batchUpdate(sql, values);
        return Arrays.stream(rets).sum();
    }

    public Integer getCountOfMon(String month){
        Map<String, Object> params = null;
        String sql = String.format("select count(1) from listing%s where last_opt_month='%s'", Config.TB_CURRENT, month);
        return jdbcTemplate.queryForObject(sql, params, Integer.class);
    }


    public int updateListings(List<Listing> errListing) {
        String sql = String.format("UPDATE listing%s SET status = :status, last_opt_month = :lastOptMonth, remark = :remark WHERE id = :id", Config.TB_CURRENT);
        SqlParameterSource[] beanSources = SqlParameterSourceUtils.createBatch(errListing);

        return jdbcTemplate.batchUpdate(sql, beanSources).length;
    }
}
